import { app, shell, BrowserWindow, ipcMain, Tray, Menu, nativeImage, screen } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import logo from '../../resources/logo.png?asset'
import admin from '../../resources/admin.jpg?asset'

let isQuit = false
let windows = {
  mainWindow: null, //主窗口
  customNoticeWindow: null //鼠标经过托盘图标时出现的自定义系统通知窗口
}
let newsTimer = null
//托盘实例
let appTray = null

/**
 * 创建自定义系统通知窗口
 */
function createCustomNoticeWindow(options) {
  windows.customNoticeWindow = new BrowserWindow(
    Object.assign(
      {
        width: 220,
        minHeight: 115,
        height: 115,
        frame: false, // 无边框
        show: false,
        modal: true,
        parent: windows.mainWindow, //指定父窗口
        icon: logo, // 窗口图标
        disableAutoHideCursor: true, // 是否在打字时隐藏光标
        resizable: false, //窗口大小是否可调整
        movable: false, //窗口是否可移动
        alwaysOnTop: true, // 窗口是否永远在别的窗口的上面
        fullscreenable: false, //窗口是否可以进入全屏状态
        webPreferences: {
          preload: join(__dirname, '../preload/index.js'),
          // webSecurity: false, //禁用同源策略
          // plugins: true //是否应该启用插件
          sandbox: false,
          disableAutoHideCursor: true
        }
      },
      options
    )
  )

  windows.customNoticeWindow.loadFile(join(__dirname, '../renderer/customNoticeHtml.html')) // 加载对应的菜单栏页面
  // windows.customNoticeWindow.webContents.openDevTools()

  //监听到主窗口关闭则清空
  windows.customNoticeWindow.on('closed', () => {
    windows.customNoticeWindow = null
  })
}

/* 设置系统托盘闪烁 */
let flashTimer = null
let isFlash = false //是否闪烁，即有新消息进入
function flashFrame(isf) {
  isFlash = isf
  windows.mainWindow.flashFrame(isFlash)
  clearInterval(flashTimer)
  if (isFlash) {
    shell.beep()
    let flag = false
    flashTimer = setInterval(() => {
      flag = !flag
      if (flag) {
        appTray.setImage(nativeImage.createEmpty())
      } else {
        appTray.setImage(logo)
      }
    }, 500)
  } else {
    appTray.setImage(logo)
  }
}

//创建系统托盘
function createAppTray() {
  appTray = new Tray(logo)
  //提示文本
  appTray.setToolTip('数科帮')
  //点击打开窗口
  appTray.on('click', () => {
    //取消托盘闪烁
    flashFrame(false)
    windows.customNoticeWindow.hide()
    windows.mainWindow.maximize()
    windows.mainWindow.show()
  })

  const contextMenu = Menu.buildFromTemplate([
    {
      label: '退出',
      // type: 'normal',
      click: (e) => {
        console.log('click quit')
        isQuit = true
        app.quit()
      }
    }
  ])

  appTray.setContextMenu(contextMenu)

  //鼠标经过托盘图标时，出现自定义系统通知窗口
  if (process.platform !== 'darwin') {
    //非mac系统时出现
    const appTrayBounds = appTray.getBounds() //获取系统托盘所在位置
    createCustomNoticeWindow({ x: appTrayBounds.x, y: appTrayBounds.y }) //创建 鼠标经过托盘图标时出现的自定义系统通知窗口
    let isLeaveTray = true //存储鼠标是否离开托盘的状态
    let isLeaveTimer = null
    appTray.on('mouse-move', () => {
      if (isQuit || !isFlash) {
        isLeaveTimer && clearInterval(isLeaveTimer)
        return
      }

      if (isFlash) {
        windows.customNoticeWindow.show() //显示自定义系统通知窗口
      }

      //系统托盘鼠标经过时触发
      const appTrayBounds = appTray.getBounds() //获取系统托盘所在位置
      let params = {}
      if (isLeaveTray) {
        if (!params.x) {
          params.x = appTrayBounds.x - 220 / 2
        }
        if (!params.y) {
          params.y = appTrayBounds.y - windows.customNoticeWindow.getBounds().height
        }
        if (params.x < 0) {
          params.x = screen.getPrimaryDisplay().bounds.width - params.x
        }
        if (params.y < 0) {
          params.y = screen.getPrimaryDisplay().bounds.height - params.y
        }

        windows.customNoticeWindow.setBounds(params)
        windows.customNoticeWindow.show() //显示自定义系统通知窗口
      }
      isLeaveTray = false

      //检查鼠标是否从托盘离开
      clearInterval(isLeaveTimer)
      isLeaveTimer = setInterval(() => {
        let point = screen.getCursorScreenPoint()
        // 判断鼠标是否再托盘内
        if (
          !(
            appTrayBounds.x < point.x &&
            appTrayBounds.y < point.y &&
            point.x < appTrayBounds.x + appTrayBounds.width &&
            point.y < appTrayBounds.y + appTrayBounds.height
          )
        ) {
          // 判断鼠标是否在弹出菜单内
          let menuBounds = windows.customNoticeWindow?.getBounds()
          if (
            menuBounds &&
            menuBounds.x < point.x &&
            menuBounds.y < point.y &&
            point.x < menuBounds.x + menuBounds.width &&
            point.y < menuBounds.y + menuBounds.height
          ) {
            console.log('mouse in news 鼠标在新消息菜单内')
            return
          }
          // 触发 mouse-leave
          clearInterval(isLeaveTimer)
          windows.customNoticeWindow.hide() // 隐藏自定义系统通知窗口
          isLeaveTray = true
          console.log('mouse leave tray 鼠标离开系统托盘图标')
        } else {
          console.log('mouse in tray  鼠标在系统托盘图标内')
        }
      }, 100)
    })
  }
}

function createWindow() {
  // Create the browser window.
  windows.mainWindow = new BrowserWindow({
    // width: 900,
    // height: 670,
    // fullscreen: true,
    minWidth: 1000,
    minHeight: 670,
    show: false,
    // titleBarStyle: 'hidden',
    titleBarOverlay: {
      color: 'red',
      symbolColor: '#74b1be',
      height: 80
    },
    autoHideMenuBar: true,
    icon: logo,
    ...(process.platform === 'linux' ? { logo } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      disableAutoHideCursor: true
    }
  })

  windows.mainWindow.maximize()

  windows.mainWindow.on('close', (e) => {
    if (isQuit) return
    e.preventDefault()
    console.log('on close to min')
    windows.mainWindow.minimize()
  })

  windows.mainWindow.on('focus', () => {
    console.log('windows show=========')
    windows.mainWindow.webContents.send('electron:isFocus', true)
  })

  windows.mainWindow.on('blur', () => {
    console.log('windows hide==========')
    windows.mainWindow.webContents.send('electron:isFocus', false)
  })

  windows.mainWindow.on('ready-to-show', () => {
    windows.mainWindow.show()
  })

  windows.mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    console.log('========__dirname', __dirname)
    console.log('process.env', process.env['ELECTRON_RENDERER_URL'])
    windows.mainWindow.loadURL('http://localhost:3500/')
    // windows.mainWindow.loadFile(join(__dirname, '../renderer/customNoticeHtml.html'))
    // windows.mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
    // windows.mainWindow.loadURL('https://www.ccccdt.com/skb_login/')
    windows.mainWindow.webContents.openDevTools()
  } else {
    // windows.mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
    windows.mainWindow.loadURL('https://www.ccccdt.com/skb/skb_login/')
    // windows.mainWindow.webContents.openDevTools()
  }
  //需要到网页内部设置
  // windows.mainWindow.setTitle('数科帮')

  // 设置窗口标题的函数
  windows.mainWindow.webContents.on('did-finish-load', () => {
    windows.mainWindow.setTitle('数科帮')
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows

  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // 下载文件
  ipcMain.on('electron:downLoad', (event, url) => {
    windows.customNoticeWindow.webContents.downloadURL(url)
  })

  //监听远程页面发送的消息推送
  ipcMain.on('electron:say', (event, data) => {
    let list = data.filter((l) => l.unreadCount > 0)
    console.log('filter  message from web', list)

    //将新消息发送到子窗口消息列表
    windows.customNoticeWindow.webContents.send('electron:list', list)
    if (list.length > 0) {
      let h = list.length > 5 ? 303 : 68 + 47 * list.length
      windows.customNoticeWindow.setContentSize(220, h)
      //托盘图标闪烁
      flashFrame(true)
    } else {
      flashFrame(false)
    }
  })

  //监听远程页面退出登录
  ipcMain.on('electron:logout', (event, data) => {
    flashFrame(false)
    windows.customNoticeWindow.hide()
    // windows.mainWindow.webContents.send('electron:ignore')
  })

  //监听子窗口页面发送的消息已读
  ipcMain.on('electron:read', (event, data) => {
    flashFrame(false)
    windows.customNoticeWindow.hide()
    windows.mainWindow.maximize()
    windows.mainWindow.show()
    windows.mainWindow.webContents.send('electron:read', data)
  })
  //监听子窗口页面发送的忽略消息
  ipcMain.on('electron:ignore', (event, data) => {
    flashFrame(false)
    windows.customNoticeWindow.hide()
    windows.mainWindow.webContents.send('electron:ignore')
  })

  //监听远程页面打开新窗口
  ipcMain.on('electron:openUrl', (event, data) => {
    const newWin = new BrowserWindow({
      autoHideMenuBar: true,
      icon: logo,
      ...(process.platform === 'linux' ? { logo } : {}),
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false,
        disableAutoHideCursor: true
      }
    })
    newWin.maximize()
    newWin.loadURL(data)
  })

  //创建主窗口
  createWindow()
  //创建托盘图标
  createAppTray()
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
  newsTimer && clearInterval(newsTimer)
  flashTimer && clearInterval(flashTimer)
})

const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
  app.quit()
} else {
  app.on('second-instance', (event) => {
    if (windows.mainWindow) {
      if (windows.mainWindow.isMinimized()) windows.mainWindow.restore()
      windows.mainWindow.focus()
    }
  })
}

// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
